﻿using System;
using System.Linq;
using System.Web.Mvc;
using ExtendedMvc.Html;
using ExtendedMvc.Tests.Model;
using ExtendedMvc.Tests.Model.Entities;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace ExtendedMvc.Tests {


	/// <summary>
	///This is a test class for LiteralTest and is intended
	///to contain all LiteralTest Unit Tests
	///</summary>
	[TestClass()]
	public class LiteralTest {

		private static DummyDataSource database;
		private static ModelViewPage<Dummy> view;

		/// <summary>
		///Gets or sets the test context which provides
		///information about and functionality for the current test run.
		///</summary>
		public TestContext TestContext { get; set; }

		#region Additional test attributes
		// 
		//You can use the following additional attributes as you write your tests:
		//
		//Use ClassInitialize to run code before running the first test in the class
		[ClassInitialize()]
		public static void MyClassInitialize(TestContext testContext) {
			database = new DummyDataSource();
			var dummy = database.Dummies.All().First();
			view = MvcMockHelpers.FakeViewPage("Index", dummy);
		}

		//Use ClassCleanup to run code after all tests in a class have run
		//[ClassCleanup()]
		//public static void MyClassCleanup() {
		//}
		//
		//Use TestInitialize to run code before running each test
		[TestInitialize()]
		public void MyTestInitialize() {
		}

		//Use TestCleanup to run code after each test has run
		//[TestCleanup()]
		//public void MyTestCleanup() {
		//}
		//
		#endregion

		/// <summary>
		///A test for Literal Constructor
		///</summary>
		[TestMethod()]
		public void Literal_ContentOnly() {
			// Arrange
			var informedContent = "Test";
			var expectedOutput = string.Format("<span>{0}</span>", informedContent);

			// Act
			var literal = view.Html.Literal(informedContent);
			var output = literal.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for Literal Constructor
		///</summary>
		[TestMethod()]
		public void Literal_ForModel() {
			// Arrange
			var dummy = database.Dummies.All().First();
			var expectedOutput = string.Format("<span>{0}</span>", dummy.BasicProperty);

			// Act
			var literal = view.Html.Literal(m => m.BasicProperty);
			var output = literal.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for Literal Constructor
		///</summary>
		[TestMethod()]
		public void Literal_WithId() {
			// Arrange
			var informedContent = "Test";
			var informedId = "TestId";
			var expectedOutput = string.Format(@"<span id=""{1}"">{0}</span>", informedContent, informedId);

			// Act
			var literal = view.Html.Literal(informedContent, informedId);
			var output = literal.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		///// <summary>
		/////A test for Literal Constructor
		/////</summary>
		//[TestMethod()]
		//public void Literal_WithFormat() {
		//    // Arrange
		//    var informedContent = "Test";
		//    var informedFormat = "New {0}";
		//    var expectedOutput = string.Format("<span>{0}</span>", string.Format(informedFormat, informedContent));

		//    // Act
		//    var literal = view.Html.Literal(informedContent).Format(informedFormat);
		//    var output = literal.ToString();

		//    // Assert
		//    Assert.AreEqual<string>(expectedOutput, output);
		//}

		/// <summary>
		///A test for Literal Constructor
		///</summary>
		[TestMethod()]
		public void Literal_WithClass() {
			// Arrange
			var informedContent = "Test";
			var informedClass = "TestClass";
			var expectedOutput = string.Format(@"<span class=""{1}"">{0}</span>", informedContent, informedClass);

			// Act
			var literal = view.Html.Literal(informedContent).CssClass(informedClass);
			var output = literal.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for Literal Constructor
		///</summary>
		[TestMethod()]
		public void Literal_WithTitle() {
			// Arrange
			var informedContent = "Test";
			var informedTitle = "Test Title";
			var expectedOutput = string.Format(@"<span title=""{1}"">{0}</span>", informedContent, informedTitle);

			// Act
			var literal = view.Html.Literal(informedContent).Title(informedTitle);
			var output = literal.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for Literal Constructor
		///</summary>
		[TestMethod()]
		public void Literal_WithStyles() {
			// Arrange
			var informedContent = "Test";
			Func<string, string>[] informedStyles = new Func<string, string>[] { margin_top => "10px", display => "block" };
			var informedStyleString = "margin-top:10px; display:block;";
			var expectedOutput = string.Format(@"<span style=""{1}"">{0}</span>", informedContent, informedStyleString);

			// Act
			var literal = view.Html.Literal(informedContent).Styles(informedStyles);
			var output = literal.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for Literal Constructor
		///</summary>
		[TestMethod()]
		public void Literal_WithAddBefore() {
			// Arrange
			var informedContent = "Test";
			var somethingToAdd = "Text to Add";
			var expectedOutput = string.Format(@"{1}<span>{0}</span>", informedContent, somethingToAdd);

			// Act
			var literal = view.Html.Literal(informedContent).AddBefore(somethingToAdd);
			var output = literal.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for Literal Constructor
		///</summary>
		[TestMethod()]
		public void Literal_WithAddAfter() {
			// Arrange
			var informedContent = "Test";
			var somethingToAdd = "Text to Add";
			var expectedOutput = string.Format(@"<span>{0}</span>{1}", informedContent, somethingToAdd);

			// Act
			var literal = view.Html.Literal(informedContent).AddAfter(somethingToAdd);
			var output = literal.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for Literal Constructor
		///</summary>
		[TestMethod()]
		public void Literal_UsingRender() {
			// Arrange
			var informedContent = "Test";
			var expectedOutput = string.Format(@"<span>{0}</span>", informedContent);

			// Act
			var literal = view.Html.Literal(informedContent);
			var output = literal.Render();

			// Assert
			Assert.IsInstanceOfType(output, typeof(MvcHtmlString));
			Assert.AreEqual<string>(expectedOutput, output.ToString());
		}

		/// <summary>
		///A test for Literal Constructor
		///</summary>
		[TestMethod()]
		public void Literal_WithClick() {
			// Arrange
			var informedContent = "Test";
			var onClickEvent = "return false;";
			var expectedOutput = string.Format(@"<span onclick=""{1}"">{0}</span>", informedContent, onClickEvent);

			// Act
			var literal = view.Html.Literal(informedContent).OnClick(onClickEvent);
			var output = literal.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}

		/// <summary>
		///A test for Literal Constructor
		///</summary>
		[TestMethod()]
		public void Literal_WrapWith() {
			// Arrange
			var informedContent = "Test";
			var tagToWrap = HtmlFormatTag.Bold;
			var expectedOutput = string.Format(@"<b><span>{0}</span></b>", informedContent);

			// Act
			var literal = view.Html.Literal(informedContent).WrapWith(tagToWrap);
			var output = literal.ToString();

			// Assert
			Assert.AreEqual<string>(expectedOutput, output);
		}
	}
}
